package dev.ece.suit.hexmap;

import java.io.InputStream;
import java.util.Map;

import org.lwjgl.opengl.GL20;

import dev.ece.core.light.Material;
import dev.ece.core.light.MaterialLocationHandler;
import dev.ece.core.shader.Shader;
import dev.ece.core.texture.Texture;
import dev.ece.suit.utils.ShaderFunctions;

public class HexMapCellShader extends Shader {

	public HexMapCellShader(InputStream vertexShaderInputStream,
			InputStream pixelShaderInputStream, Map<String, String> functions) {
		super(vertexShaderInputStream, pixelShaderInputStream, functions);
	}

	@Override
	protected String getVertexHeader() {
		StringBuffer s = new StringBuffer();
		s.append(Material.getMaterialStructString());
		s.append(super.getVertexHeader());
		return s.toString();
	}

	@Override
	protected String getPixelHeader() {
		return this.getVertexHeader();
	}
	
	@Override
	protected String getVersion() {
		return "#version 330 core";
	}
	
	private MaterialLocationHandler materialLocationHanlder;
	
	private int textureHandler;
	
	private int enableHandler;
	
	private int alphaHandler;
	
	private int blendHandler;
	
	@Override
	protected void onBindAttribLocations(int program) {
		GL20.glBindAttribLocation(program, 0, "ece_Vertex");
		GL20.glBindAttribLocation(program, 1, "ece_TexCoord");
		GL20.glBindAttribLocation(program, 2, "ece_Normal");
		GL20.glBindAttribLocation(program, 3, "ece_BlendTexCoord");
	}

	@Override
	protected void onInitializeHandler(int program) {
		materialLocationHanlder = MaterialLocationHandler.newInstance(program, "material.");
		textureHandler = glGetUniformLocation("texture");
		enableHandler = glGetUniformLocation("blendEnable");
		alphaHandler = glGetUniformLocation("blendAlpha");
		blendHandler = glGetUniformLocation("blendTexture");
	}

	public void glTexture(Texture texture) {
		GL20.glUniform1i(textureHandler, texture.bind(0));
	}
	
	public void glEnable(boolean enable) {
		GL20.glUniform1i(enableHandler, enable ? 1 : 0);
	}
	
	public void glTexture(Texture alpha, Texture blend) {
		GL20.glUniform1i(alphaHandler, alpha.bind(1));
		GL20.glUniform1i(blendHandler, blend.bind(2));
	}
	
	public void glMaterial(Material material) {
		material.glUniformMaterial(materialLocationHanlder);
	}
	
	@Override
	public void clearup() {
		materialLocationHanlder.clearup();
		GL20.glDeleteShader(textureHandler);
		GL20.glDeleteShader(alphaHandler);
		GL20.glDeleteShader(blendHandler);
		GL20.glDeleteShader(enableHandler);
		super.clearup();
		materialLocationHanlder = null;
	}

	private static HexMapCellShader hexMapCellShader;
	
	public static HexMapCellShader createHexMapCellShader() {
		if(hexMapCellShader == null) {
			hexMapCellShader = new HexMapCellShader(
					HexMapCellShader.class.getClassLoader().getResourceAsStream("shaders/defer/hexmapcell.vert"),
					HexMapCellShader.class.getClassLoader().getResourceAsStream("shaders/defer/hexmapcell.frag"), 
					ShaderFunctions.getFunctions());
		}
		return hexMapCellShader;
	}
	
}
